package com.didd.core.dubbo.file;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

/**
 * dubbo全局日志filter
 *
 * @author diddd
 * @date 2019/6/24
 */
@Slf4j
@Activate(group = Constants.PROVIDER, order = 1)
public class AccessLoggerFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
        long start = System.currentTimeMillis();
        Result result = invoker.invoke(inv);
        RpcContext context = RpcContext.getContext();
        String serviceName = invoker.getInterface().getSimpleName();
        String version = invoker.getUrl().getParameter(Constants.VERSION_KEY);
        String group = invoker.getUrl().getParameter(Constants.GROUP_KEY);

        StringBuilder sn = new StringBuilder();
        sn.append(context.getRemoteHost()).append(":").append(context.getRemotePort())
                .append(" -> ").append(context.getLocalHost()).append(":").append(context.getLocalPort())
                .append(" - ");

        if (null != group && group.length() > 0) {
            sn.append(group).append("/");
        }

        sn.append("Service=[").append(serviceName).append(".").append(inv.getMethodName());

        if (null != version && version.length() > 0) {
            sn.append(":").append(version).append("]");
        }

        sn.append(", ");
        sn.append("Request=[");

        Class<?>[] types = inv.getParameterTypes();
        if (types != null && types.length > 0) {
            boolean first = true;
            for (Class<?> type : types) {
                if (first) {
                    first = false;
                } else {
                    sn.append(", ");
                }
                sn.append(type.getSimpleName());
            }
        }

        sn.append(" (");

        Object[] args = inv.getArguments();
        if (args != null && args.length > 0) {
            sn.append(JSON.toJSONString(args, SerializerFeature.WriteMapNullValue));
        }
        sn.append(")], ");
        sn.append("Response=[").append(result.getValue()).append("]");

        String time = "[" + (System.currentTimeMillis() - start) + "ms] ";
        sn.insert(0, time);

        log.info(sn.toString());
        return result;
    }


}
